package com.wlyy.bcwlw.sys;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.wlyy.bcwlw.common.exception.AuthenticationFailedException;
import com.wlyy.bcwlw.sys.audit.dao.UnprotectUrlDAO;
import com.wlyy.bcwlw.sys.audit.entity.UnprotectUrlDTO;
import com.wlyy.bcwlw.sys.user.dao.UserDAO;
import com.wlyy.bcwlw.sys.user.entity.UserDTO;
import com.wlyy.bcwlw.sys.user.entity.UserProfile;
import com.wlyy.bcwlw.sys.user.service.UserManageService;

/**
 * 
 * @ClassName. SecurityService
 * @Description. TODO
 * @author zhangyang
 * @date 2015年8月31日 下午2:56:24
 * @version V1.0
 */
@Service("securityService")
@Transactional
public class SecurityService {
	private static final Logger logger = LogManager.getLogger(SecurityService.class);
	
	private static List<String> unprotectUrlArray = null;
	private static List<String> unprotectUrlRegArray = null;
	
	private static List<String> protectedUrls = null;
	
	@Autowired
	private UserManageService userManageService;
	@Autowired
	private CacheHelper cacheHelper;
	@Autowired
	private UserDAO userDAO;
	@Autowired
	private UnprotectUrlDAO unprotectUrlDAO;
	@Autowired
	private JdbcTemplate jdbcTemplate;
	
	/**
	 * 
	* @Title. checkPermission
	* @Description. 检测当前用户是否有此路径的访问权限
	* @param uri
	* @return boolean
	* @exception.
	 */
	public boolean checkPermission(String uri) {
		if(!isURLInProtection(uri)){
			return true;
		}
		UserProfile up = SecurityContextHolder.getUserProfile();
		if (up == null || up.equals(UserProfile.ANONYMOUS)) {
			return false;
		}
		List<String> urlList = cacheHelper.getUserMenuUrls(up.getUserId());
		for (String protectUrl : urlList) {
			if (protectUrl != null && protectUrl.indexOf(uri) != -1) {
				return true;
			}
		}
		return false;
	}
	
	// URI是否受保护
	private boolean isURLInProtection(String uri) {
		if (protectedUrls == null) {
			synchronized (this) {
				if (protectedUrls == null) {
					protectedUrls = jdbcTemplate
							.queryForList("SELECT url FROM `sys_menu` WHERE url IS NOT  NULL ",String.class);
				}
			}
		}
		for (String protectedUrl : protectedUrls) {
			if (protectedUrl.contains(uri)) {
				return true;
			}
		}
		return false;
	}
	public synchronized void refreshProtectedUrls(){
		protectedUrls = jdbcTemplate.queryForList("SELECT url FROM `sys_menu` WHERE url IS NOT  NULL ",String.class);
	}
	/**
	 * 
	* @Title. getUserProfile
	* @Description. 完善用户信息
	* @param userId
	* @param ip
	* @return
	* @throws AuthenticationFailedException
	* @throws IllegalAccessException
	* @throws InvocationTargetException UserProfile
	* @exception.
	 */
	public UserProfile getUserProfile(String userId, String ip) throws AuthenticationFailedException, IllegalAccessException,
	InvocationTargetException{
		

		UserDTO user = userDAO.findById(userId);
		if (user == null) {
			return null;
		}
		
		UserProfile up = new UserProfile();
		up.setIp(ip);
		BeanUtils.copyProperties(up, user);
		userManageService.accessDecision(up);

		return up;
	}
	
	/**
	 * 
	* @Title. loadUnprotectUrlConfig
	* @Description. 加载不受限路径 void
	* @exception.
	 */
	public  void  loadUnprotectUrlConfig() {
		if(unprotectUrlArray != null) {
			return;
		}
		synchronized(this) {
			if(unprotectUrlArray == null) {
				unprotectUrlArray = new ArrayList<String>();
				unprotectUrlRegArray = new ArrayList<String>();
				List<UnprotectUrlDTO> unprotectUrl = unprotectUrlDAO.queryByObject(null);
				for (UnprotectUrlDTO dto : unprotectUrl) {
					if(dto.isRegexp()) {
						unprotectUrlRegArray.add(dto.getUrl());
					}else{
						unprotectUrlArray.add(dto.getUrl());
					}
				}
			}
		}
	}
	/**
	 * 
	* @Title. isProctectUrl
	* @Description. URI是否受保护
	* @param url
	* @return boolean
	* @exception.
	 */
	public boolean isProctectUrl(String url) {
		loadUnprotectUrlConfig();
		//去掉url中多余的/
		url = url.replaceAll("//+", "/");
		if (unprotectUrlArray != null) {
			for (String unprotectUrl : unprotectUrlArray) {
				if (unprotectUrl.trim().startsWith(url)) {
					return false;
				}
			}
		}

		if (unprotectUrlRegArray != null) {
			for (String unprotectUrlReg : unprotectUrlRegArray) {
				Pattern pattern = Pattern.compile(unprotectUrlReg);
				Matcher matcher = pattern.matcher(url);
                if (matcher.find()) {
                	return false;
                }
			}
		}
		
		
		return true;
	}
	
	/**
	 * 
	* @Title. removeUnprotectUrlArray
	* @Description. 从静态变量里删除路径
	* @param isRegxp
	* @param url void
	* @exception.
	 */
	public void removeUnprotectUrlArray(String isRegxp,String url){
		if(UnprotectUrlDTO.URL_IS_REGEXP.equals(isRegxp)){
			if(unprotectUrlRegArray.contains(url)){
				unprotectUrlRegArray.remove(url);
			}
		}else{
			if(unprotectUrlArray.contains(url)){
				unprotectUrlArray.remove(url);
			}
		}
	}
	
	/**
	 * 
	* @Title. addUnprotectUrlArray
	* @Description. 添加新路径到静态变量
	* @param isRegxp
	* @param url void
	* @exception.
	 */
	public void addUnprotectUrlArray(String isRegxp,String url){
		
		if(UnprotectUrlDTO.URL_IS_REGEXP.equals(isRegxp)){
			if(!unprotectUrlRegArray.contains(url)){
				unprotectUrlRegArray.add(url);
			}
		}else{
			if(!unprotectUrlArray.contains(url)){
				unprotectUrlArray.add(url);
			}
		}
	}
	
	
	
		
		

}
